// 测试Object"对象"的部分静态方法

class Animal {
}

// 隐式操作: Panda.prototype = new Animal()
class Panda extends Animal {
    constructor(id,name){
        super();
        this.id = id ;
        this.name = name ;
    }
}

// Panda"对象"的原型是Animal"对象"的一个实例
console.log( Panda.prototype ); // Animal {}
// 动态为Panda"对象"的原型添加属性
Panda.prototype.type = '兽类' ;
console.log( Panda.prototype ); // Animal { type: '兽类' }

let p = new Panda( 1 , '圆圆' );
console.log( p ); // Panda { id: 1, name: '圆圆' }
// Panda实例 可以从 Panda原型 上继承 type 属性
console.log( p.type ); // 兽类

// 通过 Object.prototype.hasOwnProperty 判断属性是否是自身的
console.log( p.hasOwnProperty( 'id' ) ); // true
console.log( p.hasOwnProperty( 'name' ) ); // true
console.log( p.hasOwnProperty( 'type' ) ); // false

console.log( '- - - - - - - - - - - - - - - - - - - - -' );

// 借助于 Object 中的 keys 获取 某个对象 的 自身的、可枚举的 属性 组成的数组
let keys = Object.keys( p );
// 数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 
console.log( keys ); // [ 'id', 'name' ]

// getOwnPropertyNames 返回一个由指定对象的所有自身属性的属性名组成的数组
// 包括不可枚举属性，但不包括Symbol值作为名称的属性
let names = Object.getOwnPropertyNames( p );
console.log( names );

console.log( '- - - - - - - - - - - - - - - - - - - - -' );

// 使用 对象字面量 创建 Object 实例
let user = { }
console.log( user ); // {}
console.log( Object.keys( user ) ); // []

// ECMAScript 5 中新增了 Object.defineProperty 用于为 对象定义属性
let descriptor = {
    // 设置属性值 ( 默认值是 undefined )
    value: '拐角遇到猪', 
    // 设置属性是否可以被枚举 ( 默认值是 false 表示属性不可枚举 )
    enumerable: false ,
    // 设置属性值是否可修改 ( 默认值是 false 表示属性值不可修改 )
    writable: false ,
    // 设置属性是否可配置 ( 默认值是 false 表示不可配置，比如用不可用 delete 删除属性 )
    configurable: false
}

// Object.defineProperty( object , propertyName , propertyDescriptor )
// 为 user 实例 定义 nickname 属性并设置该属性的相关特征( 取值、可写性、可枚举性、可配置性 )
Object.defineProperty( user , 'nickname' , descriptor );

console.log( Object.keys( user ) ); // []
console.log( Object.getOwnPropertyNames( user ) ); // [ 'nickname' ]

console.log( user.nickname );
user.nickname = '拐角没遇到猪' ;
console.log( user[ 'nickname' ] );

// 动态删除实例属性
delete user.nickname ;
console.log( user.nickname );

// 总结:
// 1、Object.keys( object ) 获取 object 自身的可枚举属性名
// 2、Object.getOwnPropertyNames( object ) 获取 object 自身的所有属性(但不包括Symbol值作为名称的属性)
// 3、Object.defineProperty( object , property , descriptor ) 为 object 定义 属性并设置属性的相关特征